There are three routines of interest. The first is SetColorMode at $c2f5. This is used to setup the color card size (i.e. 8x8, 8x4 etc pixels). You pass the option in register A. options are:
A = 0 no color, 16K bitmap (this is called during booting and rebooting).
A = 1 color, 16K VDC, reduced screen size. This changes the screen to 17 character lines to squeeze the attribute data into the last bit of the 16K.
A = 2 color, 8x8 cell size, 64K VDC. Back to a 20 character line screen, but needs a 64K VDC since the attribute data is stored at $4000.
A = 3, color, 8x4 cells size, 64K VDC.
A = 4, color, 8x2 cell size, 64K VDC.
Then to draw, you have two routines. The first is ColorRectangle ($c2fb). You pass the following:
r2l ($06) = starting Y
r2H ($07) = ending Y
r3 ($08/9) = starting X word
r4 ($0a/b) = ending X word
A = colour
This will fill a rectangle with the required color. This routine works both in 40 and 80 columns, but I have not checked whether or not doubling bits work on the X values (I assume they do like all 40/80 column routines).
This uses the other subroutine, ColorCard (at $c2f8). You pass this the following:
r3 ($08/9) = x location of card start (the routine adjusts to the closest 8 bit location, so you don't have to be exactly on the start of a card)
r11L ($18) = y location of card
A = color to set or color required
C (carry bit). If set, the put color into screeen. If clear then put current screen color in A.
I have just looked and it does seem that doubling bits are taken into account.